大家好,歡迎來到「Crew Up!」的架構之旅!
在接下來的 30 天,我們將從零開始,一步步打造一個名為「Crew Up!」的社交 APP。這不只是一個教學,更是一份開發日誌,記錄我們如何用專業、嚴謹的態度,去思考、設計、並實作一個真實世界的應用。
許多教學的第一步都是 flutter create
,然後直接跳進 UI 開發。但對一個專業工程師來說,真正的第一步,發生在輸入指令之後:
選擇一個能支撐我們走完全程的「架構」。
這就像是「都市計畫」。你可以隨意地在一塊空地上蓋一棟小茅屋,但如果你想建造一座能容納百萬人口、持續發展數百年的大都會,你就必須先做好都市計畫:劃分商業區、住宅區、工業區,並設計好它們之間的交通幹道。軟體架構,就是我們 APP 的「都市計畫」。
在動手寫任何一個 Widget 之前,先決定架構,是為了避免未來幾週、甚至幾個月的混亂。我們都可能經歷過這樣的專案:一開始功能很簡單,所有程式碼都寫在一起。但隨著需求增加,這個檔案變成數千行的「巨獸 (Monster)」,改一個小地方就可能引發連鎖反應,沒人敢動它。這就是缺乏架構的代價。
一個好的架構,能在以下幾個關鍵點上幫助我們:
在做出選擇前,讓我們先快速瀏覽一下當今 Flutter 生態中幾個知名的架構模式。它們大多都源自於一個共同的基礎:三層式架構 (Three-Layer Architecture)。
不同的架構模式,可以看作是對「這三層之間該如何溝通」的不同詮釋:
在決定採用 Clean Architecture 之前,讓我們先看看各種架構模式的優缺點:
考量因素 | Clean Architecture | BLoC Pattern | MVVM | 傳統 MVC |
---|---|---|---|---|
學習曲線 | 較陡峭 ⚠️ | 中等 ○ | 較平緩 ✓ | 簡單 ✓ |
可測試性 | 極高 🎯 | 高 ✓ | 中等 ○ | 低 ✗ |
大型專案適用性 | 極佳 🎯 | 良好 ✓ | 中等 ○ | 差 ✗ |
團隊協作 | 極佳 🎯 | 良好 ✓ | 一般 ○ | 差 ✗ |
維護成本 | 中等 ○ | 中等 ○ | 中等 ○ | 高 ✗ |
開發速度 | 初期慢,後期快 ○ | 穩定 ○ | 快 ✓ | 初期快,後期慢 ○ |
在「Crew Up!」專案中,我們將採用 Clean Architecture 作為最高指導原則。這並非要取代 BLoC 或 MVVM,而是將它們納入一個更宏觀、更穩固的藍圖之中。
Clean Architecture 由 Robert C. Martin (Uncle Bob) 提出,其核心思想具有革命性:
軟體的中心應該是「領域 (Domain)」,也就是核心業務邏輯,而非資料庫或框架。
這個架構只有一條至關重要的黃金準則:
依賴原則 (The Dependency Rule):所有依賴關係,都必須指向「內部」。
看到這裡,你心中可能會有個疑問:「呈現層、業務邏輯層、資料層... 這聽起來不就是傳統的『三層式架構』嗎?」
這是一個非常好的問題,答案是:它們看似相似,但在哲學上根本不同。
傳統的三層式架構是一種「線性」或「堆疊式」的結構:
UI 層 → 依賴 → 業務邏輯層 → 依賴 → 資料存取層
在這種結構下,依賴是單向穿透的。位於核心的「業務邏輯層」卻依賴於最底下的「資料存取層」。這意味著,如果你的資料庫換了、API 格式變了(資料層的細節),你的核心業務邏輯可能被迫需要修改。這就像是國家的法律,會因為邊境哨所的武器更新而需要重寫一樣,非常不合理。
而 Clean Architecture 是一種「放射狀」或「同心圓」的結構,其靈魂在於依賴反轉原則 (Dependency Inversion Principle):
Presentation 層 (UI) → 依賴 → Domain 層
Data 層 → 依賴 → Domain 層
看見關鍵了嗎?箭頭的方向完全不同。所有的依賴關係都指向中心的 Domain 層。Domain
層是立定規則的太陽,其他層都是圍繞它運行的行星,而不是一層疊一層的積木。
這個核心差異,正是 Clean Architecture 強大生命力的來源。
在我們的專案中,Clean Architecture 具體實踐為三個層次:
所有依賴關係都指向 Domain 層:
Crew Up! 作為一個社交應用,預期會有:
Clean Architecture 的優勢:
以下情況可能不適合:
為了組織好上述的架構分層,我們將採用「功能優先 (Feature-first)」的資料夾結構。
前面討論的 Presentation, Domain, Data 三層,要如何對應到我們的資料夾結構中呢?答案就在每一個「功能」資料夾內部。這種以業務功能為核心來組織程式碼的方式,能大幅提高專案的內聚性、可讀性和長期可維護性。
特性 | Feature-first (功能優先) | Layer-first (層優先) |
---|---|---|
頂層組織 | 功能 (Features) | 層 (Layers) |
功能內聚性 | 高 (同一功能的所有程式碼都在一起) | 低 (同一功能的程式碼分散在各層) |
維護性 | 較容易 (修改功能時,影響範圍集中) | 較困難 (修改時需跨多個資料夾) |
團隊協作 | 優秀 (每個團隊成員可專注一個功能) | 一般 (容易產生合併衝突) |
現在就讓我們開始動手,建立專案與檔案結構!
建立專案
flutter create crew_up
建立基本目錄結構
在 lib/
資料夾下建立以下「功能優先」的目錄結構:
lib/
├── main.dart // 專案的進入點
├── app/ // App 全域設定與配置
│ ├── config/ // 配置檔案
│ └── core/ // 核心基礎設施
├── common/ // 跨功能模組的共用程式碼
│ └── widgets/ // 可重用的 UI 元件
└── features/ // 以業務功能為核心的模組
├── activity/ // 「活動」功能模組
│ ├── data/ // Data Layer
│ ├── domain/ // Domain Layer
│ └── presentation/ // Presentation Layer
├── home/ // 「首頁」功能模組
└── notification/ // 「通知」功能模組
有了穩固的架構基礎,明天我們將開始建構 Crew Up! 的視覺語言系統。在 Day 2 - Design System 的哲學與實作中,我們將:
恭喜!我們完成了這個系列最重要的一天。
今天,我們沒有寫任何一行 App 功能程式碼,但我們完成了更關鍵的事:為「Crew Up!」這座未來的數位城市,制定了完整的都市計畫。我們劃分了商業區(Domain)、住宅區(Presentation)與交通幹道(Data),並確立了所有建設都必須遵守的核心法規(Dependency Rule)。
更重要的是,我們深入理解了:
有了這份完整的架構藍圖,往後的開發將會更有效率、更有條理,且能從容應對未來的需求變化和團隊擴展。
期待與您繼續這趟 Flutter 職人之路的探索!🚀